const fs = require('fs');
const parser = require('@babel/parser');
const traverse = require('@babel/traverse').default;
const generate = require('@babel/generator').default;
const types = require('@babel/types');

// 读取混淆的JavaScript代码
const code = fs.readFileSync('de_de_code2.js', 'utf-8');

// 解析代码为AST
const ast = parser.parse(code, {
  sourceType: 'script',
  allowReturnOutsideFunction: true
});

// 存储操作映射
const operationMap = new Map();

// 第一步：查找所有对象属性函数定义
traverse(ast, {
  AssignmentExpression(path) {
    const { left, right } = path.node;

    // 检查是否是 O["functionName"] = function(...) {...} 模式

    if (types.isMemberExpression(left) &&
        types.isStringLiteral(left.property) &&
        types.isFunctionExpression(right)) {

      const functionName = left.property.value;
      const functionBody = right.body.body;

      // 检查函数体是否只有一个return语句
      if (functionBody.length === 1 &&
          types.isReturnStatement(functionBody[0]) &&
          types.isBinaryExpression(functionBody[0].argument)) {

        const operator = functionBody[0].argument.operator;
        operationMap.set(functionName, operator);

        // 移除这个赋值表达式，因为它不再需要
        path.remove();
      }
    }
  },
  Property(path){
    const {key,value} = path.node;

    //检查是否 'asadasds' : function(...){...}
    if(types.isLiteral(key) && types.isFunctionExpression(value)){
        const functionName = key.value;
        const functionBody = value.body.body;

      // 检查函数体是否只有一个return语句
      if (functionBody.length === 1 &&
          types.isReturnStatement(functionBody[0]) &&
          types.isBinaryExpression(functionBody[0].argument)) {

        const operator = functionBody[0].argument.operator;
        operationMap.set(functionName, operator);

        // 移除这个赋值表达式，因为它不再需要
        path.remove();
      }

    }


  }
});

// 第二步：替换所有对应的函数调用
traverse(ast, {
  CallExpression(path) {
    const { callee, arguments } = path.node;

    // 检查是否是 j["functionName"](arg1, arg2) 模式
    if (types.isMemberExpression(callee) &&
        types.isStringLiteral(callee.property)) {

      const functionName = callee.property.value;

      if (operationMap.has(functionName)) {
        const operator = operationMap.get(functionName);

        // 创建二元表达式替换函数调用
        if (arguments.length === 2) {
          const binaryExpression = types.binaryExpression(
            operator,
            arguments[0],
            arguments[1]
          );

          path.replaceWith(binaryExpression);
        }
      }
    }
  }
});

// 生成反混淆后的代码
const output = generate(ast, {
  retainLines: true,
  comments: true
});

// 写入输出文件
fs.writeFileSync('de_de_de_code2.js', output.code);

console.log('反混淆完成！结果已保存到 deobfuscated_code.js');